package com.dev.toolkit.config.ds;

import com.alibaba.druid.pool.DruidDataSource;
import com.dev.toolkit.common.util.SpringBeanUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author ZhuYouBin
 * @version 1.0.0
 * @date 2024/5/22 17:11
 * @description 动态数据源工具类
 */
public class DynamicDataSourceUtil {
    private static final Logger logger = LoggerFactory.getLogger(DynamicDataSourceUtil.class);

    /**
     * 根据数据库连接信息，创建新的数据源对象
     */
    public static DruidDataSource createDataSource(DbConnectionInfo info) {
        if (info == null) {
            return null;
        }
        DruidDataSource ds = SpringBeanUtil.getBean(DsMyBatisConfig.PROTOTYPE_DATA_SOURCE_NAME, DruidDataSource.class);
        ds.setDbType(info.getDbType());
        ds.setDriverClassName(info.getDriverClassName());
        ds.setUrl(info.getUrl());
        ds.setUsername(info.getUsername());
        ds.setPassword(info.getPassword());
        return ds;
    }

    /**
     * 切换数据源
     *
     * @param dataSourceName 数据源名称
     * @param info           数据库连接信息
     */
    public static void switchDataSource(String dataSourceName, DbConnectionInfo info) {
        DruidDataSource dataSource = null;
        try {
            // 已经包含数据源，则不在创建新的
            if (!DynamicDataSource.containsDataSource(dataSourceName)) {
                // 1、获取动态数据源
                DynamicDataSource dynamicDataSource = SpringBeanUtil.getBean(DsMyBatisConfig.DYNAMIC_DATA_SOURCE_NAME, DynamicDataSource.class);
                // 2.1、创建新的数据源对象
                dataSource = createDataSource(info);
                if (dataSource == null) {
                    return;
                }
                // 2.2、初始化数据源对象
                dataSource.init();
                // 2.3、新增数据源对象
                dynamicDataSource.addDataSource(dataSourceName, dataSource);
            }
            // 4、切换到当前数据源
            DsContextHolder.switchDataSourceType(dataSourceName);
        } catch (Exception e) {
            if (dataSource != null) {
                dataSource.close();
            }
            logger.error("初始化数据源失败:", e);
            throw new RuntimeException("初始化数据源失败:", e);
        }
    }

    /**
     * 切换到当前数据源
     *
     * @param dataSourceName 数据源名称
     */
    public static void switchDataSource(String dataSourceName) {
        // 切换到当前数据源
        DsContextHolder.switchDataSourceType(dataSourceName);
    }

    /**
     * 重置数据源
     */
    public static void resetDataSource() {
        // 重置数据源
        DsContextHolder.clearDataSourceType();
    }
}